/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.repository.adaptor.method;

//import Inspur.Gsp.Caf.Generator.BaseInfoItem.*;
//import Inspur.Gsp.Caf.Generator.ClassMethodGenerator.*;
//import Inspur.Gsp.Caf.Generator.Utils.*;
//import Inspur.Gsp.Cef.Repository.*;
//import Microsoft.CodeAnalysis.*;
//import Microsoft.CodeAnalysis.CSharp.*;
//import Microsoft.CodeAnalysis.CSharp.Syntax.*;

import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.caf.generator.baseInfo.ParameterInfo;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.cef.api.repository.IRootRepository;
import com.inspur.edp.cef.designtime.api.IGspCommonDataType;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.AssoCondition;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.element.GspAssociationKey;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.cef.generator.DotNetToJavaStringHelper;
import com.inspur.edp.cef.generator.overall.CefGeneratorContext;
import com.inspur.edp.cef.generator.repository.RepositoryGenUtil;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.EntityGetAssocationDBMappingMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.RefAssociationInfo;
import com.inspur.edp.cef.repository.assembler.AssociationInfo;
import com.inspur.edp.cef.spi.entity.info.propertyinfo.ComplexUdtPropertyInfo;
import com.inspur.edp.cef.spi.jsonser.base.StringUtils;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType;
import lombok.var;
import org.eclipse.jdt.core.dom.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class InitAssosGenerator extends ClassMethodGenerator {
	private static final String ColumnsVariableName = "refColumns%1$s";
	private static final String RepVariableName = "repository%1$s";
	private IGspCommonDataType gspCommonDataType;
	private CefGeneratorContext cefGeneratorContext;
	private List<String> fields = new ArrayList<>();
//	private java.util.ArrayList<AssociationInfo> associationInfos;
//	private java.lang.Class entityReposFactory;

	public InitAssosGenerator(CefGeneratorContext cefGeneratorContext, IGspCommonDataType gspCommonDataType, java.lang.Class entityReposFactory) {
//		this.associationInfos = associationInfos;
		this.cefGeneratorContext = cefGeneratorContext;
		this.gspCommonDataType = gspCommonDataType;
//		this.entityReposFactory = entityReposFactory;
	}

	//#region Impl

	@Override
	protected boolean getIsOverride() {
		return true;
	}

	@Override
	protected String getMethodName() {
		return "initAssociations";
	}

	@Override
	protected TypeInfo getReturnType() {
		return new TypeInfo(void.class.getTypeName());
	}

	@Override
	protected ArrayList<Modifier.ModifierKeyword> getAccessModifiers() {
		ArrayList<Modifier.ModifierKeyword> list = new ArrayList<Modifier.ModifierKeyword>();
		list.add(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
		return list;
	}

	@Override
	protected java.util.ArrayList<ParameterInfo> getParameterCollection() {
		return null;
	}

	@Override
	protected Block buildMethodBody() {
		Block block = ast.newBlock();
		for(IGspCommonField commonField:gspCommonDataType.getContainElements()){
			if(commonField.getObjectType() == GspElementObjectType.Association){
				addAssociationStatements(commonField.getChildAssociations().get(0), block.statements());
			}
		}
		return block;
	}

	private void addAssociationStatements(GspAssociation associationInfo, List statements) {
		String nodeCode = associationInfo.getRefObjectCode();
		AssociationInfo  ass = getAssociationInfo(this.cefGeneratorContext, associationInfo, gspCommonDataType);
		String sourceColumn = ass.getSourceColumn();
		String targetColumn = ass.getTargetColumn();
		GspBusinessEntity businessEntity = getRefBE(associationInfo);

		//#region 获取生成repository的语法树构造
		String repositoryVarName = String.format(RepVariableName, "_" + nodeCode + "_" + targetColumn);
		VariableDeclarationStatement repositoryStatement = getRepositoryStatement(repositoryVarName, businessEntity.getGeneratedConfigID());
		statements.add(repositoryStatement);
		//#endregion

		//#region 获取创建列集合实例的语法树
		String varName = String.format(ColumnsVariableName, "_" + nodeCode + "_" + targetColumn);
		VariableDeclarationStatement initDicStatement = getInitDicStatement(varName);
		statements.add(initDicStatement);
		//#endregion

		//#region 获取添加列语法树
		buildRefColumnsStatement(varName, associationInfo, statements);

		//添加关联条件
		String assoListName = addAssConditionStatements(associationInfo, nodeCode, targetColumn, statements);
		//#endregion
		ExpressionStatement addStatement = getAddAssociationStatement(nodeCode, targetColumn, sourceColumn, repositoryVarName, varName, businessEntity.getGeneratedConfigID(), assoListName);
		//生成过滤条件
		statements.add(addStatement);
	}

	private String addAssConditionStatements(GspAssociation gspAssociation, String nodeCode, String targetColumn, List<Statement> statements){
		if(gspAssociation.getAssoConditions() == null || gspAssociation.getAssoConditions().size() == 0){
			return null;
		}
		addImport(com.inspur.edp.cef.repository.assembler.AssoCondition.class.getTypeName());
		//ArrayList<AssoCondition> assoCondi_node1_asso = new ArrayList<>();
		String listName = "assoList_" + nodeCode + "_" + targetColumn;
		ParameterizedType parameterizedType = ast.newParameterizedType(ast.newSimpleType(ast.newSimpleName("ArrayList")));
		String assoCondiClassName = "AssoCondition";
		parameterizedType.typeArguments().add(ast.newSimpleType(ast.newSimpleName(assoCondiClassName)));
		VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
		variableDeclarationFragment.setName(ast.newSimpleName(listName));

		ParameterizedType parameterizedType1 = ast.newParameterizedType(ast.newSimpleType(ast.newSimpleName("ArrayList")));
		ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
		classInstanceCreation.setType(parameterizedType1);
		variableDeclarationFragment.setInitializer(classInstanceCreation);
		VariableDeclarationStatement variableDeclarationStatement = ast.newVariableDeclarationStatement(variableDeclarationFragment);
		variableDeclarationStatement.setType(parameterizedType);
		statements.add(variableDeclarationStatement);
//		AssoCondition assoCondition1 = new AssoCondition();
//		assoCondition1.setLeftNodeCode("Ass1");
//		assoCondition1.setLeftField("a2");
//		assoCondition1.setRightNodeCode("Ass2");
//		assoCondition1.setRightField("b2");
//		list.add(assoCondition1);
		for(int i=0; i< gspAssociation.getAssoConditions().size(); i++){
			AssoCondition assoCondition = gspAssociation.getAssoConditions().get(i);
			String assoName = "assCondi" +targetColumn + i;
			VariableDeclarationFragment assoFragment = ast.newVariableDeclarationFragment();
			assoFragment.setName(ast.newSimpleName(assoName));
			ClassInstanceCreation assoInstance = ast.newClassInstanceCreation();
			assoInstance.setType(ast.newSimpleType(ast.newSimpleName(assoCondiClassName)));
			assoFragment.setInitializer(assoInstance);
			VariableDeclarationStatement assoVarStatement = ast.newVariableDeclarationStatement(assoFragment);
			assoVarStatement.setType(ast.newSimpleType(ast.newSimpleName(assoCondiClassName)));
			statements.add(assoVarStatement);

//			assoCondition1.setLeftNodeCode("Ass1");
			MethodInvocation leftNodeMethod = ast.newMethodInvocation();
			leftNodeMethod.setExpression(ast.newSimpleName(assoName));
			leftNodeMethod.setName(ast.newSimpleName("setLeftNodeCode"));
			StringLiteral leftNodeLiteral = ast.newStringLiteral();
			leftNodeLiteral.setLiteralValue(assoCondition.getLeftNodeCode());
			leftNodeMethod.arguments().add(leftNodeLiteral);
			ExpressionStatement leftNodeExpression = ast.newExpressionStatement(leftNodeMethod);
			statements.add(leftNodeExpression);

//			assoCondition1.setLeftField("a2");
			MethodInvocation leftFieldMethod = ast.newMethodInvocation();
			leftFieldMethod.setExpression(ast.newSimpleName(assoName));
			leftFieldMethod.setName(ast.newSimpleName("setLeftField"));
			StringLiteral leftFieldLiteral = ast.newStringLiteral();
			leftFieldLiteral.setLiteralValue(assoCondition.getLeftField());
			leftFieldMethod.arguments().add(leftFieldLiteral);
			ExpressionStatement leftFieldExpression = ast.newExpressionStatement(leftFieldMethod);
			statements.add(leftFieldExpression);

//			assoCondition1.setOperator("=");
			MethodInvocation operatorMethod = ast.newMethodInvocation();
			operatorMethod.setExpression(ast.newSimpleName(assoName));
			operatorMethod.setName(ast.newSimpleName("setOperator"));
			StringLiteral operatorLiteral = ast.newStringLiteral();
			operatorLiteral.setLiteralValue(assoCondition.getOperator());
			operatorMethod.arguments().add(operatorLiteral);
			ExpressionStatement operatorExpression = ast.newExpressionStatement(operatorMethod);
			statements.add(operatorExpression);

			//			assoCondition1.setRightNodeCode("Ass2");
			MethodInvocation rightNodeMethod = ast.newMethodInvocation();
			rightNodeMethod.setExpression(ast.newSimpleName(assoName));
			rightNodeMethod.setName(ast.newSimpleName("setRightNodeCode"));
			StringLiteral rightNodeLiteral = ast.newStringLiteral();
			rightNodeLiteral.setLiteralValue(assoCondition.getRightNodeCode());
			rightNodeMethod.arguments().add(rightNodeLiteral);
			ExpressionStatement rightNodeExpression = ast.newExpressionStatement(rightNodeMethod);
			statements.add(rightNodeExpression);

			//			assoCondition1.setRightField("ass2");
			MethodInvocation rightFieldMethod = ast.newMethodInvocation();
			rightFieldMethod.setExpression(ast.newSimpleName(assoName));
			rightFieldMethod.setName(ast.newSimpleName("setRightField"));
			StringLiteral rightFieldLiteral = ast.newStringLiteral();
			rightFieldLiteral.setLiteralValue(assoCondition.getRightField());
			rightFieldMethod.arguments().add(rightFieldLiteral);
			ExpressionStatement rightFieldExpression = ast.newExpressionStatement(rightFieldMethod);
			statements.add(rightFieldExpression);

			//			assoCondition1.setValue("'test'");
			MethodInvocation valueMethod = ast.newMethodInvocation();
			valueMethod.setExpression(ast.newSimpleName(assoName));
			valueMethod.setName(ast.newSimpleName("setValue"));
			StringLiteral valueLiteral = ast.newStringLiteral();
			valueLiteral.setLiteralValue(assoCondition.getValue());
			valueMethod.arguments().add(valueLiteral);
			ExpressionStatement valueExpression = ast.newExpressionStatement(valueMethod);
			statements.add(valueExpression);

			MethodInvocation listAdd = ast.newMethodInvocation();
			listAdd.setExpression(ast.newSimpleName(listName));
			listAdd.setName(ast.newSimpleName("add"));
			listAdd.arguments().add(ast.newSimpleName(assoName));
			ExpressionStatement listAddExpression = ast.newExpressionStatement(listAdd);
			statements.add(listAddExpression);
		}
		return listName;
	}
	private GspBusinessEntity getRefBE(GspAssociation assocaition) {
		GspMetadata refMd = null; // 获取关联BE的元数据
		try {
			refMd = this.cefGeneratorContext.getMetadata(assocaition.getRefModelPkgName(), assocaition.getRefModelID());
		} catch (Exception e) {
			throw new RuntimeException("关联元数据" + assocaition.getRefModelCode() + "获取失败", e);
		}
		GspBusinessEntity beEntity =
				(GspBusinessEntity)
						((refMd.getContent() instanceof GspBusinessEntity)
								? refMd.getContent()
								: null); // 关联的BE
		return beEntity;
//		if (beEntity == null) {
//			throw new RuntimeException("关联元数据" + assocaition.getRefModelCode() + "获取失败,当前获取到的类型是" + refMd.getContent().getClass().getName());
//		}
//
//		String befConfig = beEntity.getGeneratedConfigID(); // 关联的BE的BefConfig
//		String nodeCode = assocaition.getRefObjectCode(); // 关联的BE的节点编号
//		if (DotNetToJavaStringHelper.isNullOrEmpty(nodeCode)) {
//			nodeCode = beEntity.getMainObject().getCode();
//		}
//		String mainCode = beEntity.getMainObject().getCode();
//		return new String[]{befConfig, nodeCode, mainCode};
	}

	public static AssociationInfo getAssociationInfo(CefGeneratorContext cefGeneratorContext, GspAssociation gspAssociation, IGspCommonDataType gspCommonDataType){
		AssociationInfo associationInfo = new AssociationInfo();
		String sourceElementId = "";
		String targetElementId = "";
		for(GspAssociationKey key: gspAssociation.getKeyCollection()){
			sourceElementId = key.getSourceElement();
			targetElementId = key.getTargetElement();
		}
		for(IGspCommonField gspCommonField: gspCommonDataType.getContainElements()){
			if(gspCommonField.getID().equals(targetElementId)){
				associationInfo.setTargetColumn(gspCommonField.getLabelID());
				break;
			}
		}

		//获取target
		GspMetadata metadata = cefGeneratorContext.getMetadataJitContext().
				getMetadata(gspAssociation.getRefModelID());
		GspBusinessEntity gspBusinessEntity = (GspBusinessEntity)metadata.getContent();
		IGspCommonObject refObject = gspBusinessEntity.findObjectById(gspAssociation.getRefObjectID());
		for(IGspCommonField refField:refObject.getContainElements()){
			if(refField.getID().equals(sourceElementId)){
				associationInfo.setSourceColumn(refField.getLabelID());
				break;
			}
		}
		return associationInfo;
	}

	private ExpressionStatement getAddAssociationStatement(String nodeCode, String sourceColumn, String targetColumn, String repositoryName, String columnsName, String configId, String assoListName) {
		java.util.ArrayList tokenList = new java.util.ArrayList();

		StringLiteral nodeCodeArgument = getStringArgument(nodeCode);
		tokenList.add(nodeCodeArgument);

		StringLiteral sourceNameArgument = getStringArgument(sourceColumn);
		tokenList.add(sourceNameArgument);

		StringLiteral targetNameArgument = getStringArgument(targetColumn);
		tokenList.add(targetNameArgument);

		Expression repVarArgument = getVariableArgument(repositoryName);
		tokenList.add(repVarArgument);

		Expression columnsArgument = getVariableArgument(columnsName);
		tokenList.add(columnsArgument);

		StringLiteral configIdArgument = getStringArgument(configId);
		tokenList.add(configIdArgument);

		if(!StringUtils.isEmpty(assoListName)){
			Expression assoListArgument = getVariableArgument(assoListName);
			tokenList.add(assoListArgument);
		}

		String methodName = "addAssociationInfo";
		SuperMethodInvocation invocation = ast.newSuperMethodInvocation();
		invocation.arguments().addAll(tokenList);
		invocation.setName(ast.newSimpleName(methodName));
		return ast.newExpressionStatement(invocation);
	}

	private Expression getVariableArgument(String varName) {
		return RepositoryGenUtil.createVariableLiteral(ast, varName);
	}

	private StringLiteral getStringArgument(String value) {
		return RepositoryGenUtil.createStringLiteral(ast, value);
	}

	/**
	 * IRootRepository rootRepository = (RepositoryFactory.class.newInstance()).createRepository("configId");
	 *
	 * @param varName
	 * @param configId
	 * @return
	 */
	private VariableDeclarationStatement getRepositoryStatement(String varName, String configId) {
		Type typeName = RepositoryGenUtil.getTypeByClass(ast, IRootRepository.class);
//		ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
//		classInstanceCreation.setType(ast.newSimpleType(ast.newName(entityReposFactory.getTypeName())));

		MethodInvocation methodInvocation1=ast.newMethodInvocation();
		methodInvocation1.setName(ast.newSimpleName("getBefRepositoryFactory"));
		methodInvocation1.setExpression(ast.newName("com.inspur.edp.bef.api.lcp.LcpFactoryManagerUtils"));
		String methodName = "createRepository";
		ArrayList arguments = new ArrayList();
		arguments.add(RepositoryGenUtil.createStringLiteral(ast, configId));
		MethodInvocation methodInvocation = RepositoryGenUtil.createMethodInvocation(ast, methodInvocation1, methodName, arguments);
		return RepositoryGenUtil.createVariableDeclarationStatement(ast, varName, typeName, methodInvocation);
	}

	/**
	 * Map<String,String> varName=new Map<String,String>;
	 *
	 * @param varName
	 * @return
	 */
	private VariableDeclarationStatement getInitDicStatement(String varName) {
		ParameterizedType hashMapType = ast.newParameterizedType(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(HashMap.class).getType(ast));
		Type stringType = RepositoryGenUtil.getTypeByClass(ast, String.class);
		hashMapType.typeArguments().add(stringType);
		hashMapType.typeArguments().add(RepositoryGenUtil.getTypeByClass(ast, String.class));

		ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
		classInstanceCreation.setType(hashMapType);
		ParameterizedType hashMapType1 = ast.newParameterizedType(new com.inspur.edp.caf.generator.baseInfo.TypeInfo(HashMap.class).getType(ast));
		Type stringType1 = RepositoryGenUtil.getTypeByClass(ast, String.class);
		hashMapType1.typeArguments().add(stringType1);
		hashMapType1.typeArguments().add(RepositoryGenUtil.getTypeByClass(ast, String.class));
		return RepositoryGenUtil.createVariableDeclarationStatement(ast, varName, hashMapType1, classInstanceCreation);
	}


//	refColumns_ptbe2_udt12.put("udt12_gludt2_code","code");
//refColumns_ptbe2_udt12.put("udt12_gludt2_name","name");
//refColumns_ptbe2_udt12.put("udt12_gludt2_gla","gla");
//refColumns_ptbe2_udt12.put("udt12_gludt2_gla_code","gla_code");
//refColumns_ptbe2_udt12.put("udt12_gludt2_gla_name","gla_name");
//refColumns_ptbe2_udt12.put("udt12_gludt2_gludtb","gludtb");
//refColumns_ptbe2_udt12.put("udt12_gludt2_gludtb_gl22_code","gludtb_gl22_code");
//refColumns_ptbe2_udt12.put("udt12_gludt2_gludtb_gl22_name","gludtb_gl22_name");
//refColumns_ptbe2_udt12.put("udt12_gla_code","gla_code");
//refColumns_ptbe2_udt12.put("udt12_gla_name","gla_name");
	private void buildRefColumnsStatement(String varName, GspAssociation association,  List<Statement> statements) {
		for(IGspCommonField field:association.getRefElementCollection()){
			RefAssociationInfo refAssociationInfo = getRefAssociation(cefGeneratorContext, field, association);
			if(fields.contains(refAssociationInfo.getRefField().getLabelID()))
				continue;
			if(field.getIsUdt()){
				UnifiedDataTypeDef udtDef=(UnifiedDataTypeDef)this.cefGeneratorContext.getMetadataJitContext().getMetadata(field.getUdtID()).getContent();
				if(udtDef instanceof ComplexDataTypeDef && ((ComplexDataTypeDef)udtDef).getDbInfo().getMappingType() == ColumnMapType.MultiColumns){
					//
					GspMetadata metadata = cefGeneratorContext.getMetadataJitContext().
							getMetadata(association.getRefModelID());
					if(metadata.getContent() instanceof GspBusinessEntity) {
						GspBusinessEntity gspBusinessEntity = (GspBusinessEntity) metadata.getContent();
						IGspCommonField gspCommonField = gspBusinessEntity.findElementById(field.getRefElementId());
						if(gspCommonField.getChildElements() != null && gspCommonField.getChildElements().size() >0){
							for(IGspCommonField udtfield: gspCommonField.getChildElements()){
								String preLabel = field.getLabelID().substring(0, field.getLabelID().lastIndexOf("_"));
								Statement statement = getAddDicStatement(varName, preLabel + "_" + udtfield.getLabelID(), udtfield.getLabelID());
								statements.add(statement);
							}
						}
					}
					continue;
				}
			}
			Statement statement = getAddDicStatement(varName, field.getLabelID(), refAssociationInfo.getRefField().getLabelID());
			statements.add(statement);
			if(field.getObjectType() == GspElementObjectType.Association){//
				GspMetadata metadata = cefGeneratorContext.getMetadataJitContext().
						getMetadata(association.getRefModelID());
				if(metadata.getContent() instanceof GspBusinessEntity){
					GspBusinessEntity gspBusinessEntity = (GspBusinessEntity)metadata.getContent();
					IGspCommonField gspCommonField = gspBusinessEntity.findElementById(field.getRefElementId());
					if(gspCommonField.getObjectType() == GspElementObjectType.Association){
						for(var item : gspCommonField.getChildAssociations().get(0).getRefElementCollection()){
							GspMetadata refmetadata = cefGeneratorContext.getMetadataJitContext().
									getMetadata(gspCommonField.getChildAssociations().get(0).getRefModelID());
							if(refmetadata.getContent() instanceof GspBusinessEntity){
								GspBusinessEntity refBusinessEntity = (GspBusinessEntity) refmetadata.getContent();
								IGspCommonField refCommonField = refBusinessEntity.findElementById(item.getRefElementId());
								if(gspCommonField.getIsUdt()){
//									udt12_gludt2_gludtb_gludtb_gl22_name
									String preLabel = field.getLabelID().substring(0, field.getLabelID().lastIndexOf("_"));
									Statement statementRef = getAddDicStatement(varName, preLabel + "_" + item.getLabelID(), item.getLabelID());
									statements.add(statementRef);
									fields.add(item.getLabelID());
								}else {
									Statement statementRef = getAddDicStatement(varName, field.getLabelID() + "_" + refCommonField.getLabelID(), refAssociationInfo.getRefField().getLabelID() + "_" + refCommonField.getLabelID());
									statements.add(statementRef);
									fields.add(refAssociationInfo.getRefField().getLabelID() + "_" + refCommonField.getLabelID());
								}

							}
						}
					}
				}
			}
		}
	}

	public RefAssociationInfo getRefAssociation(CefGeneratorContext cefGeneratorContext, IGspCommonField refElementField, GspAssociation gspAssociation){
		RefAssociationInfo refAssociationInfo = new RefAssociationInfo();

//		if(commonField.getChildAssociations() != null && commonField.getChildAssociations().size() > 0){
			GspMetadata metadata = cefGeneratorContext.getMetadataJitContext().
					getMetadata(gspAssociation.getRefModelID());
			GspBusinessEntity gspBusinessEntity = (GspBusinessEntity)metadata.getContent();
			IGspCommonObject refObject = gspBusinessEntity.findObjectById(gspAssociation.getRefObjectID());
			for(IGspCommonField field: refObject.getContainElements()){
				if(field.getID().equals(refElementField.getRefElementId())){
					refAssociationInfo.setRefField(field);
					refAssociationInfo.setGspAssociation(gspAssociation);
					refAssociationInfo.setField(refElementField);
					return refAssociationInfo;
				}
			}
			IGspCommonField refField = refObject.findElement(refElementField.getRefElementId());
			if(refField != null){
				refAssociationInfo.setRefField(refField);
				refAssociationInfo.setGspAssociation(refField.getParentAssociation());
			}

		return refAssociationInfo;
	}

	/**
	 * varName.put(sourceElement, targetElement);
	 *
	 * @param varName
	 * @param sourceElement
	 * @param targetElement
	 * @return
	 */
	private Statement getAddDicStatement(String varName, String sourceElement, String targetElement) {
		String methodName = "put";
		ArrayList arguments = new ArrayList();
		arguments.add(RepositoryGenUtil.createStringLiteral(ast, sourceElement));
		arguments.add(RepositoryGenUtil.createStringLiteral(ast, targetElement));
		return ast.newExpressionStatement(RepositoryGenUtil.createMethodInvocation(ast, ast.newSimpleName(varName), methodName, arguments));

	}
//#endregion
}
